home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
assemblr
/
library
/
sampler0
/
vmode.asm
< prev
next >
Wrap
Assembly Source File
|
1986-07-05
|
11KB
|
386 lines
page 58,132
title VMODE -- An Enhanced Video Mode Utility
name ADVMODE
comment *
This program will set the video mode to all possible settings.
It can be menu or command-line driven.
*
;----------------------------
; Define required Equates
STDIN equ 0
STDOUT equ 1
STDERR equ 2
BLNK equ 20h
EOS equ 0
TAB equ 9
LF equ 0ah
CR equ 0dh
TERM equ '$'
;----------------------------
; Define required MACROS
@EXIT macro RTNCODE ;; Terminate program with return code
mov ax,4c&RTNCODE&h ; Request term with return code
int 21h ; Call PC-DOS
endm
@READ macro BUFFER,FH ;; DOS 2.0+ Read from File Macro
lea dx,BUFFER ; Load Buffer addr in DX
mov cx,BUFFER&_LEN ; Load Buffer Length in CX
mov bx,FH ; Load File/Device Handle in BX
mov ah,3fh ; Request DOS read
int 21h ; Call PC-DOS
endm
@WRITE macro STRING,FH ;; DOS 2.0+ Write to File Macro
lea dx,STRING ; Load String addr in DX
mov cx,STRING&_LEN ; Load String Length in CX
mov bx,FH ; Load File Handle in BX
mov ah,40h ; Request DOS write to file/device
int 21h ; Call PC-DOS
endm
GRP group CSEG,DSEGA,DSEGB ; All segments in same segment
assume cs:GRP,ds:GRP,es:GRP,ss:GRP
DSEGB segment byte public 'STRING'
public LOGO, CRLF, MENU, PROBLEM, INVALID, DOS_ERR, QUERY
LOGO db CR,LF,'Video MODE -- A Enhanced Video Mode Setting Utility V1.0'
db CR,LF,'Copyright 1968 -- MoonWare ALL RIGHTS RESERVED'
CRLF label byte
db CR,LF,LF
CRLF_LEN equ $ - CRLF
LOGO_LEN equ $ - LOGO
MENU db 'Mode Type Size Colors Adapter',CR,LF
db ' 0 Text 40x25 16(gray) CGA,EGA,PCjr',CR,LF
db ' 1 Text 40x25 16/8 CGA,EGA,PCjr',CR,LF
db ' 2 Text 80x25 16(gray) CGA,EGA,PCjr',CR,LF
db ' 3 Text 80x25 16/8 CGA,EGA,PCjr',CR,LF
db ' 4 Graphics 320x200 4 CGA,EGA,PCjr',CR,LF
db ' 5 Graphics 320x200 4(gray) CGA,EGA,PCjr',CR,LF
db ' 6 Graphics 640x200 2 CGA,EGA,PCjr',CR,LF
db ' 7 Text 80x25 b\w EGA,MA',CR,LF
db ' 8 Graphics 160x200 16 PCjr',CR,LF
db ' 9 Graphics 320x200 16 PCjr',CR,LF
db ' 10 Graphics 640x200 4 PCjr',CR,LF
db ' 13 Graphics 320x200 16 EGA',CR,LF
db ' 14 Graphics 640x200 16 EGA',CR,LF
db ' 15 Graphics 640x350 b\w EGA',CR,LF
db ' 16 Graphics 640x350 64 EGA',CR,LF
db LF,'Enter desired mode: '
MENU_LEN equ $ - MENU
QUERY db ' ?: '
QUERY_LEN equ $ - QUERY
DOS_ERR db CR,LF,'VMODE: Need DOS 2.0+',CR,LF,TERM
INVALID db CR,LF,'VMODE: Invalid Mode',CR,LF,TAB,'Aborting...',CR,LF,LF
INVALID_LEN equ $ - INVALID
PROBLEM db 'ERROR: Video Mode was not properly set'
PROBLEM_LEN equ $ - PROBLEM
db '***** 6 July 1986 -- Raymond Moon *****'
DSEGB ends
DSEGA segment byte public 'DATA'
public BUFFER, MODE
BUFFER db 5 dup (?)
BUFFER_LEN equ $ - BUFFER
MODE dw ? ; Value for the Video Mode
DSEGA ends
CSEG segment para public 'CODE'
;-----------------------------
; Define all procedures as public for debugging
public MAIN, DISPLAY_MENU, ABORT, CMDLN, CONVERT, VALID
public PRINT_QUERY, SET_MODE
public PARMS, PARM_LEN
;-----------------------------
; Define Command Line arguments located in the PSP
org 80h
PARM_LEN db ?
PARMS db 127 dup(?)
;-----------------------------
; MAIN procedure parses the Command Line
org 100h ; .COM file format
MAIN proc near
mov ah,30h ; Request DOS Version
int 21h ; Call PC-DOS
cmp al,2 ; Is it 2 or better
jae MN0 ; OK, continue
mov ah,9 ; Request DOS Print
lea dx,DOS_ERR ; Load addr of message in DX
int 21h ; Call PC-DOS
int 20h ; Terminate the program
MN0: cmp PARM_LEN,0 ; Are there any Command Line arguments
jne MN1 ; Yes, process them
call DISPLAY_MENU ; No, go to DISPLAY_MENU
MN1: xor cx,cx ; Null CX
push cx ; This ensures last *argv ends in NUL
mov cl,PARM_LEN ; Get # of bytes in Command Line
inc cl ; Increment CL to ensure round up
and cx,0feh ; Force an even count
mov ax,sp ; Get SP
mov bp,sp ; Set BP to last byte of Cmd Ln
sub ax,cx ; Subtract PARM_LEN
mov sp,ax ; Reset SP, room on Stack
lea si,PARMS ; Load source addr in SI
mov di,sp ; Load destin addr in DI
cld ; Ensure Direction Flag is up
rep movsb ; Move Command Line onto the Stack
;-----------------------------
; Convert all blanks in the Command Line to Nul
mov bx,bp ; BX points to last byte of Cmd Ln
MN2: mov al,[bx] ; Get byte
cmp al,BLNK ; Is it a blank?
ja MN3 ; No, go set up to get another
xor al,al ; Nul AX
mov [bx],al ; Store Nul in [BX]
MN3: dec bx ; BX point to next byte
cmp bx,sp ; Are we through yet?
jnb MN2 ; No, go one mo' 'gin
;-----------------------------
; Build *argv[]. argc kept in CX. DX used as IN_WORD flag
xor cx,cx ; Set CX (argc) to 0
xor dx,dx ; Set DX to NOT_INWORD
mov bx,bp ; BX point to last byte
mov bp,sp ; BP now points to Top of Stack
MN4: mov al,[bx] ; Get byte
cmp al,0 ; Is it Nul?
jne MN5 ; No, it is a char
cmp dx,0 ; Was the last byte not a char?
je MN6 ; Yes, go on with the processing
xor dx,dx ; No, it was a char. Clear INWORD.
inc cx ; Increment argc
inc bx ; BX points to Cmd Ln arg
push bx ; Push addr onto stack
dec bx ; Reset BX
jmp short MN6 ; Go set up for another byte
MN5: inc dx ; Set DX to INWORD
MN6: dec bx ; BX point to next byte
cmp bx,bp ; Are we at the 1st byte yet?
jnb MN4 ; No, go process another
;-----------------------------
; Set up for and call CMDLN
push cx ; Push ARGC onto stack
call CMDLN ; Call Cmd Ln processor
MAIN endp
;----------------------------
; DISPLAY_MENU will display the LOGO and MENU, read in the desired mode,
; and process the response for appropriateness.
DISPLAY_MENU proc near
@WRITE LOGO,STDOUT ; Print LOGO
@WRITE MENU,STDOUT ; Print MENU
DM1: @READ BUFFER,STDIN ; Get response
call CONVERT
;----------------------------
; Was the response a number?
jnc DM2 ; CONVERT returned ok
call PRINT_QUERY ; Display QUERY
jmp DM1 ; Try again
;----------------------------
; Ensure desired mode is valid.
DM2: call VALID
jnc DM3 ; OK, continue
call PRINT_QUERY ; Display Query
jmp DM1 ; Try again
;---------------------------
; Menu is finished, Call SET_MODE
DM3: call SET_MODE
DISPLAY_MENU endp
;----------------------------
; This procedure prints QUERY on the screen.
PRINT_QUERY proc near
@WRITE QUERY,STDERR
ret
PRINT_QUERY endp
;----------------------------
; This procedure checks to see if the response was valid, 0-10 & 13-16.
VALID proc near
cmp MODE,11 ; Is MODE = 11?
je VD1 ; Yes, go to error return
cmp MODE,12 ; Is MODE = 12?
je VD1 ; Yes, go to error return
cmp MODE,16 ; Is MODE > 16?
ja VD1 ; Yes, go to error return
clc ; Clear carry flag
ret ; Return with valid response
VD1: stc ; Set carry flag
ret ; Return with invalid response
VALID endp
;----------------------------
; This procedure processes the command line
CMDLN_PARMS struc ; CMDLN passed parameter addr struc
dw ?,? ; Saved BP and IP
ARGC dw ?
ARGV dw ?
CMDLN_PARMS ends
CMDLN proc near
push bp ; Std entry logic
mov bp,sp
;----------------------------
; Transfer ARGV[1] to BUFFER
lea di,BUFFER ; Load addr of BUFFER in DI
mov si,[bp].ARGV ; Load addr of CMDLN arg in SI
mov cx,25 ; Max len in CX
CN1: lodsb ; Get next char
cmp al,EOS ; Is it EOS?
je CN3 ; Yes, stop
stosb ; Store it
dec cx ; Decrement CX
jcxz CN2 ; Gone too far, input invalid
jmp CN1 ; Continue
CN2: call ABORT ; Error out
;----------------------------
; Convert it to binary and check for a valid response.
CN3: call CONVERT ; Convert it
jnc CN4 ; Good, continue
call ABORT ; No, Error out
;----------------------------
; Check to see if response was valid.
CN4: call VALID
jnc CN5 ; Yes, continue
call ABORT ; No, Error out
;---------------------------
; Input is valid, Go set mode
CN5: call SET_MODE
CMDLN endp
;----------------------------
; This procedure aborts the program when in the Command Line mode.
; An error message is printed and the program terminated with a
; return code of 1.
ABORT proc near
@WRITE INVALID,STDERR ; Let user know somethings wrong
@EXIT 01 ; Terminate with indicated code
ABORT endp
;----------------------------
; This procedure sets the video mode and checks to see if it was
; properly set.
SET_MODE proc near
mov ax,MODE ; Put MODE into AX
int 10h ; Call VIDEO_IO (ROM BIOS)
mov ah,0fh ; Request video mode
int 10h ; Call VIDEO_IO (ROM BIOS)
xor ah,ah ; Nul AH
cmp ax,MODE ; Are they the same?
jne SM1 ; No, go tell the user
;----------------------------
; Display LOGO as sign of every thing OK and terminate program.
@WRITE LOGO,STDOUT ; Display LOGO
@EXIT 00 ; Terminate
;----------------------------
; Let user know that there was a problem, and terminate.
SM1: @WRITE LOGO,STDERR ; Display LOGO
@WRITE PROBLEM,STDERR ; Display Error message
@EXIT 01 ; Terminate with return code
SET_MODE endp
;----------------------------
; This procedure converts the ASCII string in buffer into a binary
; integer in MODE. If any errors are detected, the procedure returns
; with the Carry Flag set.
CONVERT proc near
;----------------------------
; Set up for conversion loop. Buffer length starts in CX. BH is
; used as INWORD flag.
mov cx,5 ; Put BUFFER length in CX
mov bx,000ah ; INWORD flag = FALSE, BL = 10
xor dx,dx ; Clear DX
mov ax,dx ; Clear AX
lea si,BUFFER ; SI => BUFFER
;----------------------------
; Start conversion.
CT1: lodsb ; Get next char
sub al,'0' ; Convert to number
jb CT2 ; Was below '0', not INWORD yet
cmp al,9 ; Is it or below?
ja CT2 ; It wasn't a number, not INWORD yet
xchg al,dl ; Save it
mul bl ; Multiply by 10
add dl,al ; Add new value
inc bh ; Ensure INWORD is set
jmp short CT3 ; Jump to loop inst
CT2: cmp bh,0 ; Is INWORD set?
jne CT4 ; Yes, we're finished
CT3: loop CT1 ; Go again
;----------------------------
; If the program got here with INWORD = FALSE, there was a problem.
; Return error.
cmp bh,0 ; Is INWORD set?
jne CT4 ; No, we're OK
stc ; Set Carry Flag
ret
;----------------------------
; Put result into MODE and return.
CT4: mov MODE,dx ; Store result
clc ; Ensure Carry Flag is clear
ret
CONVERT endp
CSEG ends
end MAIN